package cn.fl.dk.web.service.impl;

import cmm.comm.facade.framework.api.ISysDictionaryApiService;
import cmm.comm.facade.framework.dto.SysDictionaryDTO;
import cmm.mid.core.framework.dto.DataResultDTO;
import cmm.mid.core.framework.page.DataResultVO;
import cmm.mid.core.framework.page.Pager;
import cmm.user.facade.system.api.ISysOrgApiService;
import cmm.user.facade.system.dto.SysOrgDTO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.constant.BaseExceptionConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.logger.eum.LogExceptionEnum;
import cn.cmm.base.framework.utils.*;
import cn.fl.capital.condition.CapOverdueInfoQueryCondition;
import cn.fl.capital.condition.CapPayInfoQueryCondition;
import cn.fl.capital.dto.CapPayInfoDTO;
import cn.fl.capital.service.ICapOverdueInfoService;
import cn.fl.capital.service.ICapPayInfoApiService;
import cn.fl.capital.service.ICapPayInfoService;
import cn.fl.capital.vo.CapOverdueInfoVO;
import cn.fl.customer.service.ICstBscInfoService;
import cn.fl.customer.vo.CstBscInfoVO;
import cn.fl.dk.facade.api.IDkBillDtlApiService;
import cn.fl.dk.facade.api.IDkQuestneLogApiService;
import cn.fl.dk.facade.condition.DkBillDtlQC;
import cn.fl.dk.facade.condition.DkPaySchMQC;
import cn.fl.dk.facade.constant.*;
import cn.fl.dk.facade.dto.DkBillDtlDTO;
import cn.fl.dk.facade.dto.DkPaySchMDTO;
import cn.fl.dk.facade.dto.DkQuestneLogDTO;
import cn.fl.dk.web.service.IDkBillDtlService;
import cn.fl.dk.web.service.IDkBillInfoService;
import cn.fl.dk.web.service.IDkRuleInfoService;
import cn.fl.dk.web.transform.DkBillDtlVOTransform;
import cn.fl.dk.web.transform.DkPaySchMVOTransform;
import cn.fl.dk.web.vo.DkBillDtlVO;
import cn.fl.dk.web.vo.DkBillInfoVO;
import cn.fl.dk.web.vo.DkPaySchMVO;
import cn.fl.dk.web.vo.DkRuleInfoVO;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.project.condition.PrjPrdDtlQueryCondition;
import cn.fl.project.condition.PrjPrdPaySchMQueryCondition;
import cn.fl.project.dto.PrjPrdDtlDTO;
import cn.fl.project.dto.PrjPrdPaySchMDTO;
import cn.fl.project.service.IPrjPrdPaySchDService;
import cn.fl.project.service.IPrjPrdPaySchMApiService;
import cn.fl.project.service.IPrjPrdPaySchMService;
import cn.fl.project.service.IProjectApiService;
import cn.fl.ref.fncprjbscinfo.service.IFncPrjBscInfoService;
import cn.fl.ref.fncprjbscinfo.vo.FncPrjBscInfoVO;
import fl.ref.asspackinfo.dto.FncPrjPayRltvInfoDTO;
import fl.ref.asspackinfo.service.IAssPackInfoApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 垫款单明细表 客户端服务层接口实现
 * @Description: 业务层方法名称前缀：新增：add* 删除：remove* 修改：modify* 查询对象：select* get* 批量：batch* 查询集合：search*
 */
@Service
public class DkBillDtlServiceImpl implements IDkBillDtlService {
	/**
	 * 日志
	 */
	//private static final Logger logger = LoggerFactory.getLogger(DkBillDtlServiceImpl.class);
	
	/**
	 * 自定义 API 自行注入需要的API服务
	 */
	@Autowired
	private IDkBillDtlApiService dkBillDtlApiService;
	@Autowired
    private IDkBillInfoService dkBillInfoService;
	@Autowired
	private IFncPrjBscInfoService fncPrjBscInfoService;
	@Autowired
    private IAssPackInfoApiService assPackInfoApiService;
	@Autowired
    private ICapOverdueInfoService capOverdueInfoService;
	@Autowired
    private IDkRuleInfoService dkRuleInfoService;
	@Autowired
	private IProjectApiService projectApiService;
	@Autowired
	private IDkQuestneLogApiService dkQuestneLogApiService;
	@Autowired
	private IPrjPrdPaySchMApiService prjPrdPaySchMApiService;
	@Autowired
	private ISysOrgApiService sysOrgApiService;
	@Autowired
	private ICstBscInfoService cstBscInfoService;
	@Autowired
	private ISysDictionaryApiService sysDictionaryApiService;
    @Autowired
    private IPrjPrdPaySchDService prjPrdPaySchDService;
    @Autowired
    private ICapPayInfoService capPayInfoService;
    @Autowired
    private ICapPayInfoApiService capPayInfoApiService;

	@Override
	public DkBillDtlVO selectById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.newLogger("主键参数不能为空!").setKeys("selectById",CurrentThreadContext.getCurrentUserName()).info();
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "获取对象主键不能为空!");
		}
		DkBillDtlDTO dto = dkBillDtlApiService.selectDkBillDtlById(id);
		return DkBillDtlVOTransform.toVO(dto);
	}

	/**
	 * (non-Javadoc)
	 * @see cn.fl.dk.web.service.IDkBillDtlService#add(cn.fl.dk.web.vo.DkBillDtlVO)
	 */
	@Override
	public Long add(DkBillDtlVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.newLogger("新增对象不存在!").setKeys("add",CurrentThreadContext.getCurrentUserName()).info();
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"新增对象不存在!");
		}
		DkBillDtlDTO dto = DkBillDtlVOTransform.toDTO(entity);
		return this.dkBillDtlApiService.addDkBillDtl(dto);
	}

	@Override
	public boolean removeById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.newLogger("删除对象主键不能为空!").setKeys("removeById",CurrentThreadContext.getCurrentUserName()).info();
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"删除对象主键不能为空!");
		}
		//return this.dkBillDtlApiService.removeDkBillDtlDTOById(id);
		//TODO 业务逻辑
		return false;
	}
	
	/**
     * 删除
     * @param ids
     * @return
     */
    public boolean removeByIds(List<Long> ids)throws BaseException{
		if(CollectionUtils.isEmpty(ids)){
			BaseLogUtils.newLogger("删除主键参数集合不能为空!").setKeys("removeByIds",CurrentThreadContext.getCurrentUserName()).info();
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"删除对象主键不能为空!");
		}
		return false;
    }

	@Override
	public boolean modify(DkBillDtlVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.newLogger("修改对象不能为空!").setKeys("modify",CurrentThreadContext.getCurrentUserName()).info();
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"修改对象不能为空!");
		}
		return this.dkBillDtlApiService.modifyDkBillDtl(DkBillDtlVOTransform.toDTO(entity));
	}

	@Override
	public Pager searchListPage(Pager page) throws BaseException{
		DkBillDtlQC condition=null;
		if(null == page) {
			page = new Pager();
			page.setCondition(new DkBillDtlQC());
		}
		try{
			return this.dkBillDtlApiService.searchDkBillDtlListPage(page);
		}catch (BaseException e) {
			BaseLogUtils.newLogger("查询失败!").setKeys("searchDkBillDtlListPage",CurrentThreadContext.getCurrentUserName()).setThrowable(e).error(LogExceptionEnum.DATA_CODE_0201);
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_603, BaseExceptionConstant.BASE_EXCEPTION_CODE_603_NAME);
		} catch(Exception e){
			BaseLogUtils.newLogger("查询失败!").setKeys("searchDkBillDtlListPage",CurrentThreadContext.getCurrentUserName()).setThrowable(e).error(LogExceptionEnum.DATA_CODE_0201);
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_603, BaseExceptionConstant.BASE_EXCEPTION_CODE_603_NAME);
		}
	}

	/**
	 * 1): >= 60 t 的数据不推送问卷，直接标记赎回 ,并且這部分数据不推送问卷 
	 * 
	 * 2)、需要 逾期天数 >= 起垫逾期天数 的数据 ,否则数据不需要处理
	 * 
	 * 3)、根据支付表状态 处理--select * from SYS_DICTIONARY d where d.CODE_GRP_CD like '%PRJ0037%';
	 * 		如果状态是：
	 * 			1、拖回已处置 S0106020101；
	 *  		2、优车已处置 S01060203010101
	 *  		3、拖回赎回中 S01060202
	 *  		4、拖回转优车中S01060203
	 *  		5、拖回已转优车S0106020301
	 *  		6、优车处置中 S010602030101
	 *  		处理成 -执行赎回
	 *
	 *  	如果状态是：
	 *  		1、已拖回 S010602;
	 *  		2、拖回处置中S01060201
	 *  		我司账户 或者 机构账户 ： 处理状态是垫付 否则处理成 赎回
	 *
	 *  	注：并且以上这部分数据不用推送问卷了
	 *
	 *  4): 需要推送问卷的数据 :
	 *  	正常出险 S0101、
	 *  	罚息减免中 S0102、
	 *  	正常 S01、
	 * 		支付表状态是: 正常出险 S0101;  推送问卷的时候 标示为 “已出险试卷”（试卷类型：0 未出险试卷  1 已出险试卷），否则标记为 0
	 * 
	 * 5):数据入库
	 * 		1、同一个垫付单下，垫付明细：
	 * 			有：数据只做更新
	 * 					已垫付的 或者 已赎回的数据 就不再次更新数据了，否则更新数据
	 * 			没有：数据做插入
	 *  	2、需要推送问卷的数据入库，并且推送问卷
	 *  
	 * (non-Javadoc)
	 * @see cn.fl.dk.web.service.IDkBillDtlService#addAndpushQuestionnaire(java.lang.Long)
	 */
	@Override
	public DataResultVO addAndpushQuestionnaire(Long billId) throws BaseException {
		DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, "操作成功!");
		// 垫付单
		DkBillInfoVO billInfo = this.dkBillInfoService.selectById(Long.valueOf(billId));
		if(null == billInfo){
			result.setSuccess(BaseConstant.IS_YESNO_NO);
			result.setInfo("获取垫付单数据不存在");
			BaseLogUtils.newLogger("获取垫付单数据不存在!").setKeys("addAndpushQuestionnaire","billId="+billId,CurrentThreadContext.getCurrentUserName()).info();
			return result;
		}

		// 也删除 或者 也结束的垫付单 不用再次执行推送等 
		if(DkBillInfoConstant.BILL_STS_CD_JS.equals(billInfo.getBillStsCd())  || DkBillInfoConstant.BILL_IS_DEL_1.intValue() == billInfo.getIsDel().intValue() ){
			result.setSuccess(BaseConstant.IS_YESNO_NO);
			result.setInfo("获取垫付单数据已结束，不用再次发起推送");
			BaseLogUtils.newLogger("获取垫付单数据已结束，不用再次发起推送!").setKeys("addAndpushQuestionnaire","billId="+billId,CurrentThreadContext.getCurrentUserName()).info();
			return result;
		}
		
		// 再融资项目
		FncPrjBscInfoVO prj=this.fncPrjBscInfoService.selectById(billInfo.getRefPrjId());
		if(null == prj){
			BaseLogUtils.newLogger("再融资项目数据,数据不存在!").setKeys("addAndpushQuestionnaire","billId="+billId,CurrentThreadContext.getCurrentUserName()).info();
			result.setSuccess(BaseConstant.IS_YESNO_NO);
			result.setInfo("再融资项目数据不存在");
			return result;
		}
		
		if(prj.getAsspackid() == null){
			result.setSuccess(BaseConstant.IS_YESNO_NO);
			result.setInfo("再融资项目数据不存在");
			return result;
		}

		// 根据资产包ID获取融资项目与支付关联表信息
		List<FncPrjPayRltvInfoDTO> fncPrjPayList = this.assPackInfoApiService.selectByAssPackId(prj.getAsspackid());
		if (CollectionUtils.isEmpty(fncPrjPayList)) {
			BaseLogUtils.newLogger("根据资产包ID获取融资项目与支付关联表信息,数据不存在!").setKeys("addAndpushQuestionnaire","AssPackId="+prj.getAsspackid(),CurrentThreadContext.getCurrentUserName()).info();
			result.setSuccess(BaseConstant.IS_YESNO_NO);
			result.setInfo("根据资产包ID获取融资项目与支付关联表信息,数据不存在");
			return result;
		}
		List<Long> paySchIdList = new ArrayList<Long>();
		for(FncPrjPayRltvInfoDTO dto : fncPrjPayList){
			paySchIdList.add(dto.getPaySchId());
		}
		DkRuleInfoVO ruleInfo = this.dkRuleInfoService.selectById(Long.valueOf(billInfo.getRuleId()));
		if(CollectionUtils.isNotEmpty(paySchIdList)){
			// 起租日过滤
			PrjPrdPaySchMQueryCondition qc = new PrjPrdPaySchMQueryCondition();
			qc.setIdList(paySchIdList);
			String lsDtStart = ruleInfo.getLsDtStart();
			if(StringUtils.isNotEmpty(lsDtStart)){
				qc.setLsDtMin(DateUtils.formatStringToDate(lsDtStart,DateUtils.YYYY_MM_DD));
			}
			String lsDtEnd = ruleInfo.getLsDtEnd();
			if(StringUtils.isNotEmpty(lsDtEnd)){
				qc.setLsDtMax(DateUtils.formatStringToDate(lsDtEnd,DateUtils.YYYY_MM_DD));
			}
			List<PrjPrdPaySchMDTO> prjPrdPaySchMDTOS = this.prjPrdPaySchMApiService.searchPrjPrdPaySchMList(qc);
			if(CollectionUtils.isNotEmpty(prjPrdPaySchMDTOS)){
				paySchIdList = prjPrdPaySchMDTOS.stream().map(PrjPrdPaySchMDTO::getId).collect(Collectors.toList());
			}
		}
		if (CollectionUtils.isEmpty(paySchIdList)) {
			BaseLogUtils.newLogger("支付关联表信息,数据不存在!").setKeys("addAndpushQuestionnaire",CurrentThreadContext.getCurrentUserName()).info();
			result.setSuccess(BaseConstant.IS_YESNO_NO);
			result.setInfo("支付关联表信息,数据不存在");
			return result;
		}

		// 支付表 逾期数据
		List<CapOverdueInfoVO> capOverdueList = null;
		CapOverdueInfoQueryCondition ovdQueryCondition = new CapOverdueInfoQueryCondition();
		ovdQueryCondition.setCreateDate(new Date());// 查询创建时间是当天的  就是最新的逾期数据
		ovdQueryCondition.setPaySchIdList(paySchIdList);
		capOverdueList = this.capOverdueInfoService.searchOvdDtlList(ovdQueryCondition);
		if (CollectionUtils.isEmpty(capOverdueList)) {
			BaseLogUtils.newLogger("支付表 逾期数据 ,数据不存在!").setKeys("addAndpushQuestionnaire",CurrentThreadContext.getCurrentUserName()).info();
			result.setSuccess(BaseConstant.IS_YESNO_YES);
			result.setInfo("支付表没有逾期数据");
			return result;
		}
		
		// 贴出逾期天数 或者 逾期金额为0 的数据
		List<CapOverdueInfoVO>  capOverdueList1 = new ArrayList<CapOverdueInfoVO>();
		for(CapOverdueInfoVO overdueInfo : capOverdueList){
			if(overdueInfo.getOverdueDay() <= 0 || overdueInfo.getOverdueAmount() <= 0 ){
				continue;
			}else{
				capOverdueList1.add(overdueInfo);
			}
		}

		if (CollectionUtils.isEmpty(capOverdueList1)) {
			BaseLogUtils.newLogger("支付表 逾期数据 ,数据不存在!").setKeys("addAndpushQuestionnaire",CurrentThreadContext.getCurrentUserName()).info();
			result.setSuccess(BaseConstant.IS_YESNO_YES);
			result.setInfo("支付表没有逾期数据");
			return result;
		}
		
		List<CapOverdueInfoVO> insertVoerdueList = new ArrayList<CapOverdueInfoVO>();
		List<DkBillDtlVO> pushList = new ArrayList<DkBillDtlVO>(); // 要推送问卷

		for(CapOverdueInfoVO overdueInfo : capOverdueList1){
			// 查询产品明细表
			PrjPrdDtlQueryCondition prjPrdDtlQc = new PrjPrdDtlQueryCondition();
			prjPrdDtlQc.setPaySchId(overdueInfo.getPaySchId());
			List<PrjPrdDtlDTO> prjPrdDtls= projectApiService.selectPrjPrdDtlList(prjPrdDtlQc);
			if (CollectionUtils.isNotEmpty(prjPrdDtls)){
				
				PrjPrdDtlDTO dtlVo = prjPrdDtls.get(0);
				String stsCd = dtlVo.getPrdStsCd();
				if(StringUtils.isEmpty(stsCd)){
					continue;
				}
				
				//  逾期天数 >= 60 直接标记赎回 
				if(overdueInfo.getOverdueDay() >= DkRuleInfoConstant.DK_RULE_OVERDUEMAXDAY){
					pushList.add(getBillDtlVO(billInfo,overdueInfo,DkBillDtlConstant.CALC_RST_CD_2,stsCd));// 赎回
					continue;
				}
				
				// 需要 逾期天数 >= 起垫逾期天数 的数据 ,否则数据不需要处理
				if(overdueInfo.getOverdueDay() >= ruleInfo.getStartOvedayDays()){
					/*	支付表状态是(资产状态)：*/
					if(PrdStsCdConstant.PRD_STS_CD_THYCZ.equals(stsCd)
							|| PrdStsCdConstant.PRD_STS_CD_YCYCZ.equals(stsCd)
							|| PrdStsCdConstant.PRD_STS_CD_THSHZ.equals(stsCd)
							|| PrdStsCdConstant.PRD_STS_CD_THZYCZ.equals(stsCd)
							|| PrdStsCdConstant.PRD_STS_CD_THYZYCZ.equals(stsCd)
							|| PrdStsCdConstant.PRD_STS_CD_YCCZZ.equals(stsCd)
							){
						DkBillDtlVO entity  = getBillDtlVO(billInfo,overdueInfo,DkBillDtlConstant.CALC_RST_CD_2,stsCd);
						entity.setIsPushQus(DkBillDtlConstant.DTL_IS_PUSHQUS_1);
						pushList.add(entity);// 赎回
						continue;
					} else if(PrdStsCdConstant.PRD_STS_CD_YTH.equals(stsCd) || PrdStsCdConstant.PRD_STS_CD_THCZZ.equals(stsCd)){
						DkBillDtlVO entity = new DkBillDtlVO();
						if(DkRuleInfoConstant.DK_RULE_ACCTYPCD_WS.equals(ruleInfo.getAccTypCd()) || DkRuleInfoConstant.DK_RULE_ACCTYPCD_JG.equals(ruleInfo.getAccTypCd())){//我司账户 或者 机构账户  --垫付
							entity = getBillDtlVO(billInfo,overdueInfo,DkBillDtlConstant.CALC_RST_CD_1,stsCd);
						}else{// 赎回
							entity = getBillDtlVO(billInfo,overdueInfo,DkBillDtlConstant.CALC_RST_CD_2,stsCd);
						}
						entity.setIsPushQus(DkBillDtlConstant.DTL_IS_PUSHQUS_0);
						pushList.add(entity);
						continue;
					}else if(PrdStsCdConstant.PRD_STS_CD_ZC.equals(stsCd) || PrdStsCdConstant.PRD_STS_CD_ZCCX.equals(stsCd) || PrdStsCdConstant.PRD_STS_CD_FXJMZ.equals(stsCd)){
						DkBillDtlVO entity = getBillDtlVO(billInfo,overdueInfo,DkBillDtlConstant.CALC_RST_CD_0,stsCd);
						if(PrdStsCdConstant.PRD_STS_CD_ZCCX.equals(stsCd)) {
							entity.setQtnType(DkRuleInfoConstant.DK_RULE_QTNTYPE_Y);
						}else{
							entity.setQtnType(DkRuleInfoConstant.DK_RULE_QTNTYPE_W);
						}
						entity.setIsPushQus(DkBillDtlConstant.DTL_IS_PUSHQUS_1);
						pushList.add(entity);
						continue;
					}
				}
			}
		}

		if (CollectionUtils.isEmpty(pushList)) {
			BaseLogUtils.newLogger("支付表 逾期数据 ,数据不存在!").setKeys("addAndpushQuestionnaire",CurrentThreadContext.getCurrentUserName()).info();
			result.setSuccess(BaseConstant.IS_YESNO_YES);
			result.setInfo("支付表没有逾期数据");
			return result;
		}
		
		/**
		 * X):数据入库
		 * 1、同一个垫付单下，垫付明细：
		 * 			有：数据只做更新
		 * 					已垫付的 或者 已赎回的数据 就不再次更新数据了，否则更新数据
		 * 			没有：数据做插入
		 *  2、需要推送问卷的数据入库，并且推送问卷
		 */
		for(DkBillDtlVO billDtl: pushList){
			DkBillDtlQC qc= new DkBillDtlQC();
			qc.setPaySchId(billDtl.getPaySchId());
			qc.setPaySchNo(billDtl.getPaySchNo());
			qc.setBillId(billDtl.getBillId());
			qc.setIsDel(0);
			List<DkBillDtlDTO> billDtls = dkBillDtlApiService.searchDkBillDtlList(qc);
			
			/**
			 *  插入数据 
			 */
			if (CollectionUtils.isEmpty(billDtls)) {
				this.add(billDtl);
				// 把 RuleFlag 放成 id 后面的问卷和合同要用 
				billDtls = dkBillDtlApiService.searchDkBillDtlList(qc);
				billDtl.setRuleFlag(billDtls.get(0).getId()+"");
				billDtl.setId(billDtls.get(0).getId());
				this.modify(billDtl);
			}else{
				/**
				 * 一入库的数据不插入，做更新，
				 * 		并且只更新 0空（未垫款）的数据
				 */
				if (DkBillDtlConstant.DTL_STS_CD_0.equals(billDtls.get(0).getDtlStsCd())) {// 做更新
					DkBillDtlDTO dto = billDtls.get(0);
					dto.setId(dto.getId());
					dto.setEstimateRedeemAmt(billDtl.getEstimateRedeemAmt());
					dto.setOverdueAmount(billDtl.getOverdueAmount());
					dto.setOverdueDay(billDtl.getOverdueDay());
					this.modify(DkBillDtlVOTransform.toVO(dto));
				}
			}
			
			// 推送问卷: 已推送过问卷的就不用再次推送了
			if(DkBillDtlConstant.DTL_IS_PUSHQUS_1.equals(billDtl.getIsPushQus())){
				DkQuestneLogDTO log = dkQuestneLogApiService.selectByRuleFlag(billDtl.getRuleFlag());
				if(log == null){
					DkQuestneLogDTO questneLog = new DkQuestneLogDTO();
					questneLog.setBillId(billId);
					questneLog.setRuleFlag(billDtl.getRuleFlag());
					questneLog.setQtnType(billDtl.getQtnType());
					questneLog.setBillNm(billInfo.getBillNm());
					questneLog.setCrtTm(new Date());
					questneLog.setCrtUsrId(CurrentThreadContext.getCurrentUserId());
					questneLog.setCrtUsrName(CurrentThreadContext.getCurrentUserName());
					questneLog.setIsDel(0);
					questneLog.setPaySchNo(billDtl.getPaySchNo());
					questneLog.setQtnRstCd(DkQuestneLogConstant.QTN_RST_CD_7);
					questneLog.setCstMgrOrgCd(billDtl.getCstMgrOrgCd());
					questneLog.setCstMgrOrgNm(billDtl.getCstMgrOrgNm());
					this.dkQuestneLogApiService.add(questneLog);
				}
			}
		}
		
		return result;
	}

	/**
	 * 更新垫款测算结果
	 * @return
	 */
	@Override
	public DkBillDtlVO selectByRuleFlag(String ruleFlag) {
		DkBillDtlDTO dkBillDtlDTO = this.dkBillDtlApiService.selectDkBillDtlByRuleFlag(ruleFlag);
		return DkBillDtlVOTransform.toVO(dkBillDtlDTO);
	}

	@Override
	public DataResultVO pushContract(Long billId) {
		return this.dkBillDtlApiService.pushContract(billId);
	}

	@Override
	public DataResultDTO updateCalcrstCd(String billId){
		return dkBillDtlApiService.updateCalcrstCd(billId);
	}
	
	@Override
	public List<DkBillDtlDTO> searchlListByContractLog(DkBillDtlQC condition) throws BaseException{
		return dkBillDtlApiService.searchlListByContractLog(condition);
	}

	@Override
	public DataResultDTO doDk(DkBillDtlQC dkBillDtlQC) throws BaseException {
		DataResultDTO dataResultDTO = dkBillDtlApiService.doDk(dkBillDtlQC);
		return dataResultDTO;
	}
	
	/**
	 * @Title: getBillDtlVO
	 * @param @param billInfo
	 * @param @param overdueInfo
	 * @param @param calcRstCd
	 * @param @param stsCd
	 * @param @return
	 * @author gaoyongfei
	 * @date 2018-6-29 上午9:51:20
	 * @return DkBillDtlVO 
	 * @throws
	 */
	private DkBillDtlVO getBillDtlVO(DkBillInfoVO billInfo, CapOverdueInfoVO overdueInfo,String calcRstCd,String stsCd){
		DkBillDtlVO entity = new DkBillDtlVO();
		PrjPrdPaySchMDTO  paySchM= this.prjPrdPaySchMApiService.selectPrjPrdPaySchMById(overdueInfo.getPaySchId());
		// 客户
		CstBscInfoVO bscInfo = this.cstBscInfoService.selectById(paySchM.getCstId());
		if(bscInfo != null ){
			entity.setCstId(bscInfo.getId());
			entity.setCstNm(bscInfo.getCstNm());
		}
		
		// 客户经理的组织架构
		//SysOrgDTO sysOrg = null;
		if(paySchM != null){
			CapPayInfoQueryCondition condition =new  CapPayInfoQueryCondition();
			condition.setPaySchId(paySchM.getId());
			condition.setPaySchNo(paySchM.getPaySchNo());
			List<CapPayInfoDTO>  capPays= capPayInfoApiService.searchCapPayInfoList(condition);
			if(CollectionUtils.isNotEmpty(capPays)){
				entity.setCstMgrOrgCd(capPays.get(0).getCstMgrOrgCd());
				SysOrgDTO sysorg = this.sysOrgApiService.selectSysOrgByOrgCd(capPays.get(0).getCstMgrOrgCd(), DkRuleInfoConstant.DK_RULE_PAYCOD_SYS);
				if(sysorg != null){
					entity.setCstMgrOrgNm(sysorg.getOrgNm());
				}
			}
		}
		
		SysDictionaryDTO sysdic = sysDictionaryApiService.getCode(DkRuleInfoConstant.DK_RULE_PAYCOD_SYS, DkRuleInfoConstant.DK_RULE_PAYCOD_ORG , DkRuleInfoConstant.DK_RULE_PAYCOD_GRP, stsCd);
		if(sysdic != null ){
			entity.setPrdStsCd(sysdic.getCode());
			entity.setPrdStsCdNm(sysdic.getCodeNm());
		}
		
		entity.setIsDel(0);
		entity.setCrtTm(new Date());
		entity.setCalcRstCd(calcRstCd);
		entity.setBillId(billInfo.getId());
		entity.setBillNm(billInfo.getBillNm());
		entity.setRuleId(billInfo.getRuleId());
		entity.setPaySchId(overdueInfo.getPaySchId());
		entity.setPaySchNo(overdueInfo.getPaySchNo());
		entity.setOverdueDay(overdueInfo.getOverdueDay());
		entity.setDtlStsCd(DkBillDtlConstant.DTL_STS_CD_0);
		entity.setOverdueAmount(overdueInfo.getOverdueAmount());
		entity.setCrtUsrId(CurrentThreadContext.getCurrentUserId());
		entity.setCrtUsrNm(CurrentThreadContext.getCurrentUserName());
		if(overdueInfo.getPayPd() != null){
			entity.setPayPd(overdueInfo.getPayPd().toString());
		}
		
		Long overdueAmount = 0L;
		if(overdueInfo.getOverdueAmount() == null) {
			overdueAmount = overdueInfo.getOverdueAmount();
		}
		if(DkBillDtlConstant.CALC_RST_CD_1.equals(calcRstCd)){// 垫付： 预计垫款/赎回金额 = 当前的逾期租金*（1+1.5%）
        	double amt = DecimalUtils.mul(overdueAmount,DkRuleInfoConstant.DK_RULE_DF_PERCENT,10);
        	entity.setEstimateRedeemAmt(new Double(amt).longValue());
		}else if(DkBillDtlConstant.CALC_RST_CD_2.equals(calcRstCd)){// 赎回： 剩余本金 + 当前的逾期租金 
			Long arAmt = dkBillDtlApiService.queryArAmt(overdueInfo.getPaySchId());//剩余本金
			if(arAmt == null){
				arAmt=0L;
			}
			entity.setEstimateRedeemAmt(arAmt + overdueAmount);
		}
		return entity;
	}

	@Override
	public List<DkBillDtlDTO> searchDkBillDtlList(DkBillDtlQC condition)
			throws BaseException {
		return dkBillDtlApiService.searchDkBillDtlList(condition);
	}

	/**
	 * 执行前：更新实际垫款金额 
	 * @Title: handleAfterUpdateInfo
	 * @param @param lists
	 * @author gaoyongfei
	 * @date 2018-7-2 下午7:09:50
	 * @return void 
	 * @throws
	 */
	@Override
	public void handleAfterUpdateInfo(List<DkBillDtlDTO> lists){
        List<Long> paySchIdList = new ArrayList<>();//支付主表idList
        for (DkBillDtlDTO d : lists) {
            paySchIdList.add(d.getPaySchId());
        }
        
        //查询逾期表
        CapOverdueInfoQueryCondition capOverdueInfoQc = new CapOverdueInfoQueryCondition();
        capOverdueInfoQc.setPaySchIdList(paySchIdList);
        capOverdueInfoQc.setCreateDate(new Date());//当天的逾期数据
        List<CapOverdueInfoVO>  capOverdueList = this.capOverdueInfoService.searchOvdDtlList(capOverdueInfoQc);
        Map<Long, CapOverdueInfoVO> capOverdueInfoMap = null;
        if (CollectionUtils.isNotEmpty(capOverdueList)) {
            capOverdueInfoMap = new HashMap<>();//逾期表map
            for (CapOverdueInfoVO o : capOverdueList) {
                capOverdueInfoMap.put(o.getPaySchId(), o);
            }
        }

        for (DkBillDtlDTO dtl : lists) {
            //垫付明细列表拼接逾期表数据开始
            if (CollectionUtils.isMapNotEmpty(capOverdueInfoMap) && capOverdueInfoMap.containsKey(dtl.getPaySchId())) {
            	CapOverdueInfoVO capOverdueInfoVo= capOverdueInfoMap.get(dtl.getPaySchId());
            	dtl.setOverdueDay(capOverdueInfoVo.getOverdueDay());
            	dtl.setOverdueAmount(capOverdueInfoVo.getOverdueAmount());//逾期金额(分)
                if(DkBillDtlConstant.CALC_RST_CD_1.equals(dtl.getCalcRstCd())){// 垫付： 预计垫款/赎回金额 = 当前的逾期租金*（1+1.5%）
                	double overdueAmt = capOverdueInfoVo.getOverdueAmount();
                	double amt = DecimalUtils.mul(overdueAmt,DkRuleInfoConstant.DK_RULE_DF_PERCENT,10);
                	dtl.setEstimateRedeemAmt(Math.round(amt));
                	dtl.setActualRedeemAmt(Math.round(amt));
        		}else if(DkBillDtlConstant.CALC_RST_CD_2.equals(dtl.getCalcRstCd())){// 赎回： 剩余本金 + 当前的逾期租金 
        			Long arAmt = dkBillDtlApiService.queryArAmt(capOverdueInfoVo.getPaySchId());//剩余本金
        			if(arAmt == null){
        				arAmt=0L;
        			}
        			dtl.setEstimateRedeemAmt(arAmt + capOverdueInfoVo.getOverdueAmount());
        			dtl.setActualRedeemAmt(arAmt + capOverdueInfoVo.getOverdueAmount());
        		}
                this.modify(DkBillDtlVOTransform.toVO(dtl));
            }
        }
	}

	@Override
	public List<DkPaySchMVO> selectMingDianPaySchMList(DkPaySchMQC condition) throws BaseException {
		return DkPaySchMVOTransform.toVOList(this.dkBillDtlApiService.selectMingDianPaySchMList(condition));
	}

	@Override
	public DataResultDTO doMingDian(List<Long> paySchIdList, Long ruleId, Long billId) {
		return this.dkBillDtlApiService.executeMingDian(paySchIdList,ruleId,billId,CurrentThreadContext.getCurrentUserId(),CurrentThreadContext.getCurrentUserName());
	}

	@Override
	public Pager selectMingDianPaySchMListPage(Pager pager) {
		pager = dkBillDtlApiService.selectMingDianPaySchMListPage(pager);
		List<DkPaySchMDTO> resultList = (List<DkPaySchMDTO>) pager.getResultList();
		List<DkPaySchMVO> voList = DkPaySchMVOTransform.toVOList(resultList);
		pager.setResultList(voList);
		return pager;
	}
}
